package com.pochogastos.dao;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.HashMap;

import javax.naming.NamingException;

import com.pochogastos.db.DBManager;
import com.pochogastos.model.Perfil;
import com.pochogastos.model.Usuario;

public class UsuarioDAO {
	
private static UsuarioDAO instancia;
	
	public static UsuarioDAO getInstance(){
		if(instancia == null)
			instancia = new UsuarioDAO();
		return instancia;
	}
	
	public Usuario altaUsuario(String nombre, String usuario, String pass, String mail) throws SQLException, ClassNotFoundException, NamingException{
		Connection conn = DBManager.getInstance().getConnection();
		PreparedStatement pstmt = conn.prepareStatement("INSERT INTO gastos.usuarios (nombre,usuario,pass,mail,fecha_alta) VALUES (?,?,?,?,CURDATE())", Statement.RETURN_GENERATED_KEYS);
		pstmt.setString(1, nombre);
		pstmt.setString(2, usuario);
		pstmt.setString(3, pass);
		pstmt.setString(4, mail);
		pstmt.executeUpdate();
		ResultSet rs = pstmt.getGeneratedKeys();
		rs.next();
		Usuario u = new Usuario();
		u.setMail(mail);
		u.setNombre(nombre);
		u.setPassword(pass);
		u.setUsuario(usuario);
		u.setId(String.valueOf(rs.getInt(1)));
		pstmt.close();
		return u;
	}
	
	
	public Usuario login(String usuario) throws SQLException, ClassNotFoundException, NamingException{
		Connection conn = DBManager.getInstance().getConnection();
		PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM gastos.usuarios u left join gastos.perfil p on u.id = p.id_usuario WHERE u.usuario = ?");
		pstmt.setString(1, usuario);
		ResultSet rs = pstmt.executeQuery();
		Usuario u = null;
		if(rs.next()){
			u = new Usuario();
			u.setId(String.valueOf(rs.getInt(1)));
			u.setMail(rs.getString("mail"));
			u.setNombre(rs.getString("nombre"));
			u.setPassword(rs.getString("pass"));
			u.setUsuario(rs.getString("usuario"));
			Perfil p = new Perfil();
			p.setTelefono(rs.getString("telefono")!=null?rs.getString("telefono"):"");
			u.setPerfil(p);
			pstmt = conn.prepareStatement("UPDATE gastos.usuarios SET ultimo_login = CURDATE() where usuario = ?");
			pstmt.setString(1, usuario);
			pstmt.executeUpdate();
			pstmt.close();
		}
		return u;
	}
	
	public Usuario getUsernameMail(String usuario,String mail) throws SQLException, ClassNotFoundException, NamingException{
		Connection conn = DBManager.getInstance().getConnection();
		PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM gastos.usuarios WHERE usuario = ? and mail = ?", Statement.RETURN_GENERATED_KEYS);
		pstmt.setString(1, usuario);
		pstmt.setString(2, mail);
		ResultSet rs = pstmt.executeQuery();
		Usuario u = null;
		if(rs.next()){
			u = new Usuario();
			u.setId(String.valueOf(rs.getInt(1)));
			u.setMail(rs.getString("mail"));
			u.setNombre(rs.getString("nombre"));
			u.setPassword(rs.getString("pass"));
			u.setUsuario(rs.getString("usuario"));
		}
		pstmt.close();
		return u;
	}

	public Boolean resetPassword(String encPass, String email, String usuario) throws SQLException, ClassNotFoundException, NamingException{
		Connection conn = DBManager.getInstance().getConnection();
		Usuario u = this.getUsernameMail(usuario,email);
		if(u!=null){
			PreparedStatement pstmt = conn.prepareStatement("UPDATE gastos.usuarios SET pass = ? WHERE id = ?");
			pstmt.setString(1, encPass);
			pstmt.setInt(2, Integer.parseInt(u.getId()));
			int n = pstmt.executeUpdate();
			pstmt.close();
			if(n!=0)
				return true;
			else
				return false;
		}else{
			return false;
		}
	}
	
	public void updateUsuario(String idUsuario,String email,String telefono,File imagen,String pass,String nombre) throws SQLException, ClassNotFoundException, IOException, NamingException{
		Connection conn = DBManager.getInstance().getConnection();
		FileInputStream fis0 = null;
		FileInputStream fis1 = null;
		FileInputStream fis2 = null;
		HashMap<Integer,Object> parametrosHash = new HashMap<Integer,Object>();
		int parametrosId = 1;
		
		String query = "UPDATE gastos.usuarios SET ";
		if(email!=null && !"".equalsIgnoreCase(email)){
			query += " mail = ?";
			parametrosHash.put(parametrosId, email);
			parametrosId++;
		}
		if(pass!=null && !"".equalsIgnoreCase(pass)){
			if(parametrosHash.isEmpty())
				query += " pass = ?";
			else
				query += " ,pass = ?";
			parametrosHash.put(parametrosId, pass);
			parametrosId++;
		}
		if(nombre!=null && !"".equalsIgnoreCase(nombre)){
			if(parametrosHash.isEmpty())
				query += " nombre = ?";
			else
				query += " ,nombre = ?";
			parametrosHash.put(parametrosId, nombre);
			parametrosId++;
		}
		
		query += " WHERE id = ?";
		
		PreparedStatement pstmt = conn.prepareStatement(query);
		for(Integer key: parametrosHash.keySet()){
			if (parametrosHash.get(key) instanceof String) {
				String valor = (String) parametrosHash.get(key);
				pstmt.setString(key, valor);
			}else if (parametrosHash.get(key) instanceof Integer){
				Integer valor = (Integer) parametrosHash.get(key);
				pstmt.setInt(key, valor);
			}else if (parametrosHash.get(key) instanceof File){
				File valor = (File) parametrosHash.get(key);
				fis0 = new FileInputStream(valor);
				pstmt.setBinaryStream(key, fis0, (int) valor.length());
			}
		}
		pstmt.setInt(parametrosId, Integer.parseInt(idUsuario));
		pstmt.executeUpdate();
		
		parametrosId = 1;
		parametrosHash = new HashMap<Integer,Object>();
		query = "UPDATE gastos.perfil SET";
		if(telefono!=null && !"".equalsIgnoreCase(telefono)){
			query += " telefono = ?";
			parametrosHash.put(parametrosId, telefono);
			parametrosId++;
		}
		if(imagen!=null){
			if(parametrosHash.isEmpty())
				query += " imagen = ?";
			else
				query += " ,imagen = ?";
			parametrosHash.put(parametrosId, imagen);
			parametrosId++;
		}
		query += " where id_usuario = ?";
		pstmt = conn.prepareStatement(query);
		for(Integer key: parametrosHash.keySet()){
			if (parametrosHash.get(key) instanceof String) {
				String valor = (String) parametrosHash.get(key);
				pstmt.setString(key, valor);
			}else if (parametrosHash.get(key) instanceof Integer){
				Integer valor = (Integer) parametrosHash.get(key);
				pstmt.setInt(key, valor);
			}else if (parametrosHash.get(key) instanceof File){
				File valor = (File) parametrosHash.get(key);
				fis1 = new FileInputStream(valor);
				pstmt.setBinaryStream(key, fis1, (int) valor.length());
			}
		}
		pstmt.setInt(parametrosId, Integer.parseInt(idUsuario));
		int resultado = pstmt.executeUpdate();
		if(resultado == 0){
			query = "INSERT INTO gastos.perfil(id_usuario,telefono,imagen) VALUES (?,?,?)";
			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, Integer.parseInt(idUsuario));
			if(telefono!=null && !"".equalsIgnoreCase(telefono))
				pstmt.setString(2, telefono);
			else
				pstmt.setNull(2, Types.NULL);
			if(imagen!=null){
				fis2 = new FileInputStream(imagen);
				pstmt.setBinaryStream(3, fis2, (int) imagen.length());
			}else
				pstmt.setNull(3, Types.NULL);
			resultado = pstmt.executeUpdate();
		}
		pstmt.close();
		if(fis0!=null)
			fis0.close();
		if(fis1!=null)
			fis1.close();
		if(fis2!=null)
			fis2.close();
		
	}
	
	public Blob loadImage(String idUsuario) throws ClassNotFoundException, SQLException, IOException, NamingException{
		Connection conn = DBManager.getInstance().getConnection();
		PreparedStatement pstmt = conn.prepareStatement("SELECT imagen FROM gastos.perfil WHERE id_usuario = ?");
		pstmt.setInt(1, Integer.parseInt(idUsuario));
		ResultSet rs = pstmt.executeQuery();
		Blob img = null;
		if(rs.next()){
			img = rs.getBlob(1);
		}
		pstmt.close();
		return img;
	}

}
